package simple.utils.data;

import com.google.common.io.ByteStreams;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.locks.ReentrantLock;

/**
 * Created by rehak on 4/25/14.
 */
public class CachedFile {

    private static final Logger LOGGER = LoggerFactory.getLogger(CachedFile.class);
    private final ReentrantLock poLock = new ReentrantLock();
    private final AtomicLong lastLoad = new AtomicLong(0);
    private final File f;
    private final long maxAgeMillis;
    private final AtomicReference<byte[]> data = new AtomicReference<>();

    public CachedFile(File f, long maxAge, TimeUnit maxAgeUnits) {
        this.f = f;
        this.maxAgeMillis = maxAgeUnits.toMillis(maxAge);
    }

    public InputStream getInputStream() {
        return new ByteArrayInputStream(get());
    }

    public byte[] get() {
        poLock.lock();
        try {
            // not loaded yet or too old
            if (System.currentTimeMillis() - lastLoad.get() > maxAgeMillis) {
                if (f.exists() && !f.isDirectory()) {
                    FileInputStream in = new FileInputStream(f);
                    byte[] data = ByteStreams.toByteArray(in);
                    this.data.set(data);
                    lastLoad.set(System.currentTimeMillis());
                    in.close();
                }
            }
        } catch (FileNotFoundException e) {
            LOGGER.error("File " + f.getAbsolutePath() + " not found!");
            return null;
        } catch (IOException e) {
            LOGGER.error("I/O exception reading file " + f.getAbsolutePath() + "!");
            return null;
        } finally {
            poLock.unlock();
        }
        return data.get();
    }


}
